package cz.muni.fi.pa165.languageschool.dao.impl;

import cz.muni.fi.pa165.languageschool.Lecture;
import cz.muni.fi.pa165.languageschool.Lecturer;
import cz.muni.fi.pa165.languageschool.Student;
import cz.muni.fi.pa165.languageschool.dao.LectureDao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * LectureDao implementation using JPA
 *
 * @author Michal Fučík (395624) michal.fuca.fucik(at)gmail.com
 */
public class LectureDaoImpl implements LectureDao {

    final static Logger log = LoggerFactory.getLogger(LectureDaoImpl.class);

    private EntityManager entityManager;

    public LectureDaoImpl() {
    }

    public LectureDaoImpl(EntityManager em) {
        if (em == null) {
            throw new NullPointerException("Argument em was null");
        }
        this.entityManager = em;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public Collection<Lecture> getAllLectures() {
        log.info("***** DAO Lecture - getAllLectures");
        TypedQuery<Lecture> tq = entityManager.createQuery(
                "SELECT l FROM Lecture l", Lecture.class);
        return tq.getResultList();
    }

    @Override
    public void createLecture(Lecture lecture) {
        log.info("***** DAO Lecture - createLecture: {}", lecture);
        if (lecture == null) {
            throw new NullPointerException("Argument lecture cannot be null.");
        }
        entityManager.persist(lecture);
    }

    @Override
    public Lecture getLecture(Long id) {
        log.info("***** DAO Lecture - getLecture: {}", id);
        Lecture res = null;
        if (id == null) {
            throw new NullPointerException("Argument lecture id cannot be null.");
        }

        return entityManager.find(Lecture.class, id);
    }

    @Override
    public void updateLecture(Lecture lecture) {
        log.info("***** DAO Lecture - updateLecture: {}", lecture);
        if (lecture == null) {
            throw new NullPointerException("Argument lecture cannot be null.");
        }

        Lecture lr = entityManager.find(Lecture.class, lecture.getId());
        if (lr == null) {
            throw new IllegalArgumentException("Passed entity doesn't exist in database");
        }

        lr.setCourse(lecture.getCourse());
        lr.setLabel(lecture.getLabel());
        lr.setLecturer(lecture.getLecturer());
        lr.setTopicDescription(lecture.getTopicDescription());
        lr.setTpDay(lecture.getTpDay());
        lr.setTpTime(lecture.getTpTime());

        entityManager.persist(lr);
    }

    @Override
    public void deleteLecture(Lecture lecture) {
        log.info("***** DAO Lecture - deleteLecture: {}", lecture);
        if (lecture == null) {
            throw new NullPointerException("Argument lecture cannot be null.");
        }
        Lecture lr = entityManager.find(Lecture.class, lecture.getId());
        if (lr == null) {
            throw new IllegalArgumentException("Passed entity doesn't exist in database");
        }
        entityManager.remove(lr);
    }

    @Override
    public Lecturer getLecturesLecturer(Lecture lec) {
        log.info("***** DAO Lecture - getLecturesLecturer: {}", lec);
        if (lec == null) {
            throw new NullPointerException("Argument lec was null");
        }
        Lecture lr = entityManager.find(Lecture.class, lec.getId());
        return lr.getLecturer();
    }

    @Override
    public void setLecturerToLecture(Long lectureId, Lecturer lrr) {
        log.info("***** DAO Lecture - setLecturerToLecture: {}, {}", lectureId, lrr);
        if (lectureId == null) {
            throw new NullPointerException("Argument lectureId was null");
        }
        if (lrr == null) {
            throw new NullPointerException("Argument lrr was null");
        }

        Lecture lecture = entityManager.find(Lecture.class, lectureId);
        if (lecture == null) {
            throw new IllegalArgumentException("Entity of passed id doesn't exist in database");
        }
        lecture.setLecturer(lrr);
        entityManager.merge(lrr);
        entityManager.persist(lecture);
    }

    @Override
    public List<Student> getEnrolledStudents(Lecture lec) {
        log.info("***** DAO Lecture - getEnrolledStudents: {}", lec);
        if (lec == null) {
            throw new NullPointerException("Argument lec was null");
        }

        Lecture ldb = entityManager.find(Lecture.class, lec.getId());
        if (ldb == null) {
            throw new IllegalArgumentException("Given lecture doesn't exist in database");
        }
        return ldb.getEnrolledStudents();
    }

    @Override
    public void setEnrolledStudents(Long id, List<Student> sts) {
        log.info("***** DAO Lecture - setEnrolledStudents: {}{}", id, sts);
        if (id == null) {
            throw new NullPointerException("Argument id was null");
        }
        if (sts == null) {
            throw new NullPointerException("Argument sts was null");
        }
        Lecture ldb = entityManager.find(Lecture.class, id);
        if (ldb == null) {
            throw new IllegalArgumentException("Lecture with given id is not in database");
        }
        List<Student> newList = new ArrayList<>();
        
        for (Student s : sts) {
            Student sdb = entityManager.find(Student.class, s.getId());
            if (sdb != null)
                newList.add(sdb);
        }
        ldb.setEnrolledStudents(newList);
        entityManager.persist(ldb);
    }
}
